#include "VOCUS.h"


VOCUS::VOCUS(void)
{
	this->_numOfPyrLevel = 5;	// S0 - S4
	this->_numOfPyrDiff = 2;
	this->_numOfScalePyrLevel = this->_numOfPyrLevel - this->_numOfPyrDiff;
	this->_numOfOri = 4;	// 0, 45, 90, 135
	this->_numOfColor = 4;	// red,green,blue,yellow
	this->_numOfSurScale = 2; // 3, 7
	this->_surr_scale.resize(this->_numOfSurScale);
	this->_surr_scale[0] = 3;
	this->_surr_scale[1] = 7;
	this->_ori_angle.resize(this->_numOfOri);
	this->_ori_angle[0] = 0.0f;this->_ori_angle[1] = 0.25f;
	this->_ori_angle[2] = 0.5f;this->_ori_angle[3] = 0.75f;
	this->_OnOffsize = 2;	// on-center, off-center for intensity

<<<<<<< .mine
	this->_gabor_scale = 3;
	this->_gabor_sigma = 0.25 * PI; 
=======
	this->_gabor_scale = 5;
	this->_gabor_sigma = 0.25 * PI; 
>>>>>>> .r5
	this->_gabor_f = sqrt(2.0); 

<<<<<<< .mine
	this->_localMaxThres_ratio2Global = 0.6;
	this->_floodfillRatio = 0.1;
=======
	this->_localMaxThres_ratio2Global = 0.8;
	this->_floodfillRatio = 0.25;
>>>>>>> .r5

	this->_imgPath = "no image";
	this->_originImg = NULL;
	this->_showProcess = false;
	this->_init();
}
VOCUS::~VOCUS(void)
{
	this->_release();
}

void VOCUS::run()
{
	assert(!(this->_originImg == NULL && !this->_imgPath.compare("no image")));
	if (this->_originImg == NULL)
		this->loadImageFromPath(this->_imgPath);

	time_t start_t = clock();
	time_t now_t = clock();
	cout << "Used Time: " << 1.0 * (start_t - now_t) / CLOCKS_PER_SEC << " secs." << endl;

	this->_showSingleImage("Original", this->_originImg);
	this->_showSingleImage("Gaussian", this->_Gaussian3x3Smooth(this->_originImg));

	start_t = clock();
	this->_computeIntPyr();
	now_t = clock();
	cout << "Intensity Pyramid Used Time: " << 1.0 * (start_t - now_t) / CLOCKS_PER_SEC << " secs." << endl;
	this->_showPyr("Intensity Pyramid", this->_IntImgPyr);

	start_t = clock();
	this->_computeOriLapPyr5x5();
	now_t = clock();
	cout << "Orientation Laplacian Pyramid Used Time: " << 1.0 * (start_t - now_t) / CLOCKS_PER_SEC << " secs." << endl;
	this->_showPyr("Orientation Laplacian Pyramid", this->_OriLapPyr);

	start_t = clock();
	this->_computeColPyr();
	now_t = clock();
	cout << "Color Pyramid Used Time: " << 1.0 * (start_t - now_t) / CLOCKS_PER_SEC << " secs." << endl;
	this->_showPyr("Color Pyramid Red", this->_ColImgPyr[0]);
	this->_showPyr("Color Pyramid Green", this->_ColImgPyr[1]);
	this->_showPyr("Color Pyramid Blue", this->_ColImgPyr[2]);
	this->_showPyr("Color Pyramid Yellow", this->_ColImgPyr[3]);

	start_t = clock();
	this->_computeScaleIntImgs();
	now_t = clock();
	cout << "Intensity Scale Images Used Time: " << 1.0 * (start_t - now_t) / CLOCKS_PER_SEC << " secs." << endl;
	this->_showPyr("Intensity Scale Images On 3", this->_IntScaleImgPyr[0][0]);
	this->_showPyr("Intensity Scale Images On 7", this->_IntScaleImgPyr[0][1]);
	this->_showPyr("Intensity Scale Images Off 3", this->_IntScaleImgPyr[1][0]);
	this->_showPyr("Intensity Scale Images Off 7", this->_IntScaleImgPyr[1][1]);

	start_t = clock();
	this->_computeScaleOriImgs();
	now_t = clock();
	cout << "Orientation Scale Images Used Time: " << 1.0 * (start_t - now_t) / CLOCKS_PER_SEC << " secs." << endl;
	this->_showPyr("Orientation Scale Images 0", this->_OriScaleImgPyr[0]);
	this->_showPyr("Orientation Scale Images 45", this->_OriScaleImgPyr[1]);
	this->_showPyr("Orientation Scale Images 90", this->_OriScaleImgPyr[2]);
	this->_showPyr("Orientation Scale Images 135", this->_OriScaleImgPyr[3]);

	start_t = clock();
	this->_computeScaleColImgs();
	now_t = clock();
	cout << "Color Scale Images Used Time: " << 1.0 * (start_t - now_t) / CLOCKS_PER_SEC << " secs." << endl;
	this->_showPyr("Color Scale Images r3",this->_ColScaleImgPyr[0][0]);
	this->_showPyr("Color Scale Images g3",this->_ColScaleImgPyr[1][0]);
	this->_showPyr("Color Scale Images b3",this->_ColScaleImgPyr[2][0]);
	this->_showPyr("Color Scale Images y3",this->_ColScaleImgPyr[3][0]);
	this->_showPyr("Color Scale Images r7",this->_ColScaleImgPyr[0][1]);
	this->_showPyr("Color Scale Images g7",this->_ColScaleImgPyr[1][1]);
	this->_showPyr("Color Scale Images b7",this->_ColScaleImgPyr[2][1]);
	this->_showPyr("Color Scale Images y7",this->_ColScaleImgPyr[3][1]);

	start_t = clock();
	this->_computeIntFeatureMaps();
	now_t = clock();
	cout << "Intensity Feature Used Time: " << 1.0 * (start_t - now_t) / CLOCKS_PER_SEC << " secs." << endl;
	this->_showSingleImage("inten feat on", this->_IntFeatMaps[0]);
	this->_showSingleImage("inten feat off", this->_IntFeatMaps[1]);

	start_t = clock();
	this->_computeOriFeatureMaps();
	now_t = clock();
	cout << "Orientation Feature Used Time: " << 1.0 * (start_t - now_t) / CLOCKS_PER_SEC << " secs." << endl;
	this->_showSingleImage("ori1", this->_OriFeatMaps[0]);
	this->_showSingleImage("ori2", this->_OriFeatMaps[1]);
	this->_showSingleImage("ori3", this->_OriFeatMaps[2]);
	this->_showSingleImage("ori4", this->_OriFeatMaps[3]);

	start_t = clock();
	this->_computeColFeatureMaps();
	now_t = clock();
	cout << "Color Feature Used Time: " << 1.0 * (start_t - now_t) / CLOCKS_PER_SEC << " secs." << endl;
	this->_showSingleImage("col1", this->_ColFeatMaps[0]);
	this->_showSingleImage("col2", this->_ColFeatMaps[1]);
	this->_showSingleImage("col3", this->_ColFeatMaps[2]);
	this->_showSingleImage("col4", this->_ColFeatMaps[3]);

	start_t = clock();
	this->_computeIntConsMap();
	now_t = clock();
	cout << "Intensity Conspicuity Used Time: " << 1.0 * (start_t - now_t) / CLOCKS_PER_SEC << " secs." << endl;
	this->_showSingleImage("conint", this->_IntConspImg);

	start_t = clock();
	this->_computeOriConsMap();
	now_t = clock();
	cout << "Orientation Conspicuity Used Time: " << 1.0 * (start_t - now_t) / CLOCKS_PER_SEC << " secs." << endl;
	this->_showSingleImage("conori", this->_OriConspImg);

	start_t = clock();
	this->_computeColConsMap();
	now_t = clock();
	cout << "Color Conspicuity Used Time: " << 1.0 * (start_t - now_t) / CLOCKS_PER_SEC << " secs." << endl;
	this->_showSingleImage("concol", this->_ColConspImg);

	start_t = clock();
	this->_computeSaliencyMap();
	now_t = clock();
	cout << "Saliency Map Used Time: " << 1.0 * (start_t - now_t) / CLOCKS_PER_SEC << " secs." << endl;
	this->_showSingleImage("Saliency", this->_SaliencyMap);

	start_t = clock();
	//this->_computeMSR();
	now_t = clock();
	cout << "Most Salient Region Used Time: " << 1.0 * (start_t - now_t) / CLOCKS_PER_SEC << " secs." << endl;
	this->_showSingleImage("Saliency", this->_SaliencyMap);
	//this->_computeMSR();
	//this->_computeMSR();
}

bool setParameter(vector<ParameterName> para_name, vector<float>)
{
	for (int i = 0; i < para_name.size(); i++)
	{
		switch (para_name[i])
		{

		}
	}
	return true;
}

void VOCUS::_computeIntPyr()
{
	this->_IntImgPyr[0] = cvCreateImage(cvSize(this->_originImg->width, this->_originImg->height), this->_originImg->depth, 1);
	cvCvtColor(this->_originImg, this->_IntImgPyr[0], CV_BGR2GRAY);
	for (int i = 0; i < this->_numOfPyrLevel - 1; i++)
	{
		this->_IntImgPyr[i+1] = cvCreateImage(cvSize(this->_IntImgPyr[i]->width / 2,this->_IntImgPyr[i]->height / 2),this->_IntImgPyr[i]->depth,this->_IntImgPyr[i]->nChannels);
		cvPyrDown(this->_IntImgPyr[i], this->_IntImgPyr[i + 1], CV_GAUSSIAN_5x5); 
	}
}
void VOCUS::_computeOriLapPyr3x3()
{
	this->_OriLapPyr[0] = cvCreateImage(cvSize(this->_originImg->width, this->_originImg->height), this->_originImg->depth, 1);
	cvCvtColor(this->_originImg, this->_OriLapPyr[0], CV_BGR2GRAY);
	IplImage* tmpimg;
	for (int i = 0; i < this->_numOfPyrLevel - 1; i++)
	{
		this->_OriLapPyr[i+1] = cvCreateImage(cvSize(this->_OriLapPyr[i]->width / 2,this->_OriLapPyr[i]->height / 2),this->_OriLapPyr[i]->depth,this->_OriLapPyr[i]->nChannels);
		tmpimg = this->_Gaussian3x3Smooth(this->_OriLapPyr[i]);
		cvSub(this->_OriLapPyr[i], tmpimg, this->_OriLapPyr[i]);
		cvReleaseImage(&tmpimg);
	}
	tmpimg = this->_Gaussian3x3Smooth(this->_OriLapPyr.back());
	cvSub(this->_OriLapPyr.back(), tmpimg, this->_OriLapPyr.back());
	cvReleaseImage(&tmpimg);

}
void VOCUS::_computeOriLapPyr5x5()
{
	this->_OriLapPyr[0] = cvCreateImage(cvSize(this->_originImg->width, this->_originImg->height), this->_originImg->depth, 1);
	cvCvtColor(this->_originImg, this->_OriLapPyr[0], CV_BGR2GRAY);
	IplImage* tmpimg;
	for (int i = 0; i < this->_numOfPyrLevel - 1; i++)
	{
		tmpimg = cvCreateImage(cvSize(this->_OriLapPyr[i]->width,this->_OriLapPyr[i]->height),this->_OriLapPyr[i]->depth,this->_OriLapPyr[i]->nChannels);
		this->_OriLapPyr[i+1] = cvCreateImage(cvSize(this->_OriLapPyr[i]->width / 2,this->_OriLapPyr[i]->height / 2),this->_OriLapPyr[i]->depth,this->_OriLapPyr[i]->nChannels);
		cvPyrDown(this->_OriLapPyr[i], this->_OriLapPyr[i + 1], CV_GAUSSIAN_5x5);
		cvPyrUp(this->_OriLapPyr[i+1], tmpimg, CV_GAUSSIAN_5x5);
		cvSub(this->_OriLapPyr[i], tmpimg, this->_OriLapPyr[i]);
		cvReleaseImage(&tmpimg);
	}
	tmpimg = cvCreateImage(cvSize(this->_OriLapPyr.back()->width,this->_OriLapPyr.back()->height),this->_OriLapPyr.back()->depth,this->_OriLapPyr.back()->nChannels);
	IplImage* tmpimg2 = cvCreateImage(cvSize(this->_OriLapPyr.back()->width / 2,this->_OriLapPyr.back()->height / 2),this->_OriLapPyr.back()->depth,this->_OriLapPyr.back()->nChannels);
	cvPyrDown(this->_OriLapPyr.back(), tmpimg2, CV_GAUSSIAN_5x5);
	cvPyrUp(tmpimg2, tmpimg, CV_GAUSSIAN_5x5);
	cvSub(this->_OriLapPyr.back(), tmpimg, this->_OriLapPyr.back());
	cvReleaseImage(&tmpimg);
	cvReleaseImage(&tmpimg2);
}
void VOCUS::_computeColPyr()
{
	IplImage* LabImg = cvCreateImage(cvSize(this->_originImg->width, this->_originImg->height), this->_originImg->depth, this->_originImg->nChannels);
	cvCvtColor(this->_originImg, LabImg, CV_BGR2Lab );
	int colorValue[4][2] = {{255, 127},{0, 127},{127, 255},{127, 0}};

	//IplImage* L = cvCreateImage(cvSize(this->_originImg->width, this->_originImg->height), this->_originImg->depth, 1);
	//IplImage* a = cvCreateImage(cvSize(this->_originImg->width, this->_originImg->height), this->_originImg->depth, 1);
	//IplImage* b = cvCreateImage(cvSize(this->_originImg->width, this->_originImg->height), this->_originImg->depth, 1);
	//cvSet(b,cvScalar(0),0);
	//cvMerge(L,a,b,NULL,LabImg);
	//cvCvtColor(LabImg, this->_originImg, CV_Lab2BGR);
	//cvShowImage("or", this->_originImg);
	//cvSplit(LabImg, L, a, b, NULL);
	//cvShowImage("L", L);
	//cvShowImage("a", a);
	//cvShowImage("b", b);
	//cvWaitKey(0);

	for (int i = 0; i < this->_numOfColor; i++)
		this->_ColImgPyr[i][0] = cvCreateImage(cvSize(this->_originImg->width, this->_originImg->height), this->_originImg->depth, 1);

	for (int x = 0; x < this->_ColImgPyr[0][0]->height; x++)
		for (int y = 0; y < this->_ColImgPyr[0][0]->width; y++)
		{
			int a = ((uchar*)(LabImg->imageData + LabImg->widthStep * x))[y * 3 + 1];
			int b = ((uchar*)(LabImg->imageData + LabImg->widthStep * x))[y * 3 + 2];
			//int d = (a - colorValue[i][0])*(a - colorValue[i][0]) + (b - colorValue[i][1])*(b - colorValue[i][1]);
			//((uchar*)(this->_ColImgPyr[i][0]->imageData + this->_ColImgPyr[i][0]->widthStep * x))[y] = (uchar)((int)(sqrt((double)d)+ 0.5));
			//int d = abs(a - colorValue[i][0]) + abs( b - colorValue[i][1]);
			//((uchar*)(this->_ColImgPyr[i][0]->imageData + this->_ColImgPyr[i][0]->widthStep * x))[y] = (uchar)((int)d);
			int red,green,blue,yellow;
			this->_ab2rgyb(a, b, &red, &green, &yellow, &blue);
			((uchar*)(this->_ColImgPyr[0][0]->imageData + this->_ColImgPyr[0][0]->widthStep * x))[y] = (uchar)(red);
			((uchar*)(this->_ColImgPyr[1][0]->imageData + this->_ColImgPyr[1][0]->widthStep * x))[y] = (uchar)(green);
			((uchar*)(this->_ColImgPyr[2][0]->imageData + this->_ColImgPyr[2][0]->widthStep * x))[y] = (uchar)(yellow);
			((uchar*)(this->_ColImgPyr[3][0]->imageData + this->_ColImgPyr[3][0]->widthStep * x))[y] = (uchar)(blue);
		}

	for (int i = 0; i < this->_numOfColor; i++)
	{
		for (int j = 0; j < this->_numOfPyrLevel - 1; j++)
		{
			this->_ColImgPyr[i][j+1] = cvCreateImage(cvSize(this->_ColImgPyr[i][j]->width / 2, this->_ColImgPyr[i][j]->height / 2), this->_ColImgPyr[i][j]->depth, this->_ColImgPyr[i][j]->nChannels);
			cvPyrDown(this->_ColImgPyr[i][j], this->_ColImgPyr[i][j+1], CV_GAUSSIAN_5x5); 
		}
	}

	//for (int i = 0; i < this->_numOfColor; i++)
	//{
	//	this->_ColImgPyr[i][0] = cvCreateImage(cvSize(this->_originImg->width, this->_originImg->height), this->_originImg->depth, 1);
	//	for (int x = 0; x < this->_ColImgPyr[i][0]->height; x++)
	//		for (int y = 0; y < this->_ColImgPyr[i][0]->width; y++)
	//		{
	//			int a = ((uchar*)(LabImg->imageData + LabImg->widthStep * x))[y * 3 + 1];
	//			int b = ((uchar*)(LabImg->imageData + LabImg->widthStep * x))[y * 3 + 2];
	//			//int d = (a - colorValue[i][0])*(a - colorValue[i][0]) + (b - colorValue[i][1])*(b - colorValue[i][1]);
	//			//((uchar*)(this->_ColImgPyr[i][0]->imageData + this->_ColImgPyr[i][0]->widthStep * x))[y] = (uchar)((int)(sqrt((double)d)+ 0.5));
	//			int d = abs(a - colorValue[i][0]) + abs( b - colorValue[i][1]);
	//			((uchar*)(this->_ColImgPyr[i][0]->imageData + this->_ColImgPyr[i][0]->widthStep * x))[y] = (uchar)((int)d);
	//		}
	//	for (int j = 0; j < this->_numOfPyrLevel - 1; j++)
	//	{
	//		this->_ColImgPyr[i][j+1] = cvCreateImage(cvSize(this->_ColImgPyr[i][j]->width / 2, this->_ColImgPyr[i][j]->height / 2), this->_ColImgPyr[i][j]->depth, this->_ColImgPyr[i][j]->nChannels);
	//		cvPyrDown(this->_ColImgPyr[i][j], this->_ColImgPyr[i][j+1], CV_GAUSSIAN_5x5); 
	//	}
	//	//cvShowImage("map", this->_ColImgPyr[i][0]);
	//	//cvWaitKey(0);
	//}
}

void VOCUS::_computeScaleIntImgs()
{
	//On-center
	for (int i = 0; i < this->_numOfScalePyrLevel; i++)
		for (int j = 0; j < this->_numOfSurScale; j++)
		{
			int pyr_oldID = i + this->_numOfPyrDiff;
			this->_IntScaleImgPyr[0][j][i] = cvCloneImage(this->_IntImgPyr[pyr_oldID]);
			cvSet(this->_IntScaleImgPyr[0][j][i], cvScalar(0));
			//cvShowImage("intpryon", this->_IntScaleImgPyr[0][j][i]);

			this->_OnCenterFilter(this->_IntImgPyr[pyr_oldID], this->_IntScaleImgPyr[0][j][i], this->_surr_scale[j]);

			//cvShowImage("intpryon1", this->_IntScaleImgPyr[0][j][i]);
			//cvWaitKey(0);


			//cvNormalize(this->_IntScaleImgPyr[0][j][i], this->_IntScaleImgPyr[0][j][i], 255, 0, CV_MINMAX);
		}
	//	Off-center
	for (int i = 0; i < this->_numOfScalePyrLevel; i++)
		for (int j = 0; j < this->_numOfSurScale; j++)
		{
			int pyr_oldID = i + this->_numOfPyrDiff;
			this->_IntScaleImgPyr[1][j][i] = cvCloneImage(this->_IntImgPyr[pyr_oldID]);
			cvSet(this->_IntScaleImgPyr[1][j][i], cvScalar(0));
			//cvShowImage("intpryoff", this->_IntScaleImgPyr[1][j][i]);

			this->_OffCenterFilter(this->_IntImgPyr[pyr_oldID], this->_IntScaleImgPyr[1][j][i], this->_surr_scale[j]);

			//cvShowImage("intpryoff1", this->_IntScaleImgPyr[1][j][i]);
			//cvWaitKey(0);


			//cvNormalize(this->_IntScaleImgPyr[0][j][i], this->_IntScaleImgPyr[0][j][i], 255, 0, CV_MINMAX);
		}
}
void VOCUS::_computeScaleOriImgs()
{
	for (int i = 0; i < this->_numOfOri; i++)
		for (int j = 0; j < this->_numOfScalePyrLevel; j++)
		{
			int pyr_oldID = j + this->_numOfPyrDiff;
			this->_OriScaleImgPyr[i][j] = cvCreateImage(cvSize(this->_OriLapPyr[pyr_oldID]->width, this->_OriLapPyr[pyr_oldID]->height), this->_OriLapPyr[pyr_oldID]->depth, this->_OriLapPyr[pyr_oldID]->nChannels);
			//	Make Gabor filter
			CvGabor *gabor1 = new CvGabor; gabor1->Init(PI * this->_ori_angle[i], this->_gabor_scale, this->_gabor_sigma, this->_gabor_f);
			//	Filter
			gabor1->conv_img(this->_OriLapPyr[pyr_oldID], this->_OriScaleImgPyr[i][j], CV_GABOR_MAG); 
		}
}
void VOCUS::_computeScaleColImgs()
{
	for (int i = 0; i < this->_numOfColor; i++)
		for (int j = 0; j < this->_numOfSurScale; j++)
			for (int k = 0; k < this->_numOfScalePyrLevel; k++)
			{
				int pyr_oldID = k + this->_numOfPyrDiff;
				this->_ColScaleImgPyr[i][j][k] = cvCloneImage(this->_ColImgPyr[i][pyr_oldID]);
				this->_OnCenterFilter(this->_ColImgPyr[i][pyr_oldID], this->_ColScaleImgPyr[i][j][k], this->_surr_scale[j]);
			}
}

void VOCUS::_computeIntFeatureMaps()
{
	int pic_num = this->_numOfSurScale * this->_numOfPyrLevel;
	double weight = 1.0 / pic_num;
	for (int i = 0; i < this->_OnOffsize; i++)
	{
		this->_IntFeatMaps[i] = cvCreateImage(cvSize(this->_IntScaleImgPyr[i][0][0]->width, this->_IntScaleImgPyr[i][0][0]->height), this->_IntScaleImgPyr[i][0][0]->depth, this->_IntScaleImgPyr[i][0][0]->nChannels);
		cvSet(this->_IntFeatMaps[i], cvScalar(0));
		IplImage* tmpimg = cvCreateImage(cvSize(this->_IntFeatMaps[i]->width, this->_IntFeatMaps[i]->height), this->_IntFeatMaps[i]->depth, this->_IntFeatMaps[i]->nChannels);
		IplImage* tmp = cvCreateImage(cvSize(this->_IntFeatMaps[i]->width, this->_IntFeatMaps[i]->height), this->_IntFeatMaps[i]->depth, this->_IntFeatMaps[i]->nChannels);;
		IplImage* tmp = cvCreateImage(cvSize(this->_IntScaleImgPyr[i][0][0]->width, this->_IntScaleImgPyr[i][0][0]->height), this->_IntScaleImgPyr[i][0][0]->depth, this->_IntScaleImgPyr[i][0][0]->nChannels);;
		for (int j = 0; j < this->_numOfSurScale; j++)
			for (int k = 0; k < this->_numOfScalePyrLevel; k++)
			{
				cvResize(this->_IntScaleImgPyr[i][j][k], tmpimg,CV_INTER_NN);
				//cvAdd(this->_IntFeatMaps[i], tmpimg, this->_IntFeatMaps[i]);
				//tmp = cvCloneImage(this->_IntFeatMaps[i]);
				cvCopy(this->_IntFeatMaps[i], tmp);
				cvAddWeighted(tmp, 1.0, tmpimg, (double) 1.0 / this->_numOfSurScale / this->_numOfPyrLevel, 0.0, this->_IntFeatMaps[i]);
				//cvAdd(tmp, tmpimg, this->_IntFeatMaps[i]);
				//cvShowImage("intfeat", this->_IntFeatMaps[i]);
				//cvShowImage("tmp", tmpimg);
				//cvWaitKey(0);
				//cvNormalize(this->_IntFeatMaps[i],this->_IntFeatMaps[i]);
			}
		//cvCopy(this->_IntFeatMaps[i], tmp);
		//cvScale(tmp, this->_IntFeatMaps[i], (double)1.0 / this->_numOfPyrLevel);
		//cvNormalize(this->_IntFeatMaps[i],this->_IntFeatMaps[i],255,0,CV_MINMAX,NULL);
		//cvShowImage("intfeature", this->_IntFeatMaps[i]);
		//cvWaitKey(0);
		//cvCopy(this->_IntFeatMaps[i], tmp);
		//cvNormalize(tmp, this->_IntFeatMaps[i], 255, 0, CV_MINMAX);
		cvReleaseImage(&tmpimg);	
		cvReleaseImage(&tmp);
	}
}
void VOCUS::_computeOriFeatureMaps()
{
	int pic_num = this->_numOfPyrLevel;
	double weight = 1.0 / pic_num;
	for (int i = 0; i < this->_numOfOri; i++)
	{
		this->_OriFeatMaps[i] = cvCreateImage(cvSize(this->_OriScaleImgPyr[i][0]->width, this->_OriScaleImgPyr[i][0]->height), this->_OriScaleImgPyr[i][0]->depth, this->_OriScaleImgPyr[i][0]->nChannels);
		cvSet(this->_OriFeatMaps[i], cvScalar(0));
<<<<<<< .mine
		IplImage* tmpimg = cvCreateImage(cvSize(this->_OriFeatMaps[i]->width, this->_OriFeatMaps[i]->height), this->_OriFeatMaps[i]->depth, this->_OriFeatMaps[i]->nChannels);
		IplImage* tmp = cvCreateImage(cvSize(this->_OriFeatMaps[i]->width, this->_OriFeatMaps[i]->height), this->_OriFeatMaps[i]->depth, this->_OriFeatMaps[i]->nChannels);
		for (int j = 0; j < this->_numOfScalePyrLevel; j++)
=======
		IplImage* tmpimg = cvCreateImage(cvSize(this->_OriScaleImgPyr[i][0]->width, this->_OriScaleImgPyr[i][0]->height), this->_OriScaleImgPyr[i][0]->depth, this->_OriScaleImgPyr[i][0]->nChannels);
		IplImage* tmp = cvCreateImage(cvSize(this->_OriScaleImgPyr[i][0]->width, this->_OriScaleImgPyr[i][0]->height), this->_OriScaleImgPyr[i][0]->depth, this->_OriScaleImgPyr[i][0]->nChannels);
		for (int j = 0; j < this->_numOfPyrLevel; j++)
>>>>>>> .r5
		{
			cvResize(this->_OriScaleImgPyr[i][j], tmpimg,CV_INTER_NN);
			//cvAdd(this->_IntFeatMaps[i], tmpimg, this->_IntFeatMaps[i]);
			//tmp = cvCloneImage(this->_OriFeatMaps[i]);
			cvCopy(this->_OriFeatMaps[i], tmp);
			cvAddWeighted(tmp, 1.0, tmpimg, (double)1.0 / this->_numOfPyrLevel, 0.0, this->_OriFeatMaps[i]);
			//cvAdd(tmp, tmpimg, this->_OriFeatMaps[i]);
			//cvNormalize(this->_IntFeatMaps[i],this->_IntFeatMaps[i]);
		}
		//IplImage* tmp = cvCloneImage(this->_OriFeatMaps[i]);
		//cvCopy(this->_OriFeatMaps[i], tmp);
		//cvScale(tmp, this->_OriFeatMaps[i], (double)1.0 / this->_numOfPyrLevel);
		
		//IplImage* tmp = cvCloneImage(this->_OriFeatMaps[i]);
		//cvCopy(this->_OriFeatMaps[i], tmp);
		//cvNormalize(tmp,this->_OriFeatMaps[i], 255, 0, CV_MINMAX);
		cvReleaseImage(&tmpimg);	
		cvReleaseImage(&tmp);	
	}
}
void VOCUS::_computeColFeatureMaps()
{
	int pic_num = this->_numOfSurScale * this->_numOfPyrLevel;
	double weight = 1.0 / pic_num;
	for (int i = 0; i < this->_numOfColor; i++)
	{
		this->_ColFeatMaps[i] = cvCreateImage(cvSize(this->_ColScaleImgPyr[i][0][0]->width, this->_ColScaleImgPyr[i][0][0]->height), this->_ColScaleImgPyr[i][0][0]->depth, this->_ColScaleImgPyr[i][0][0]->nChannels);
		cvSet(this->_ColFeatMaps[i], cvScalar(0));
		IplImage* tmpimg = cvCreateImage(cvSize(this->_ColFeatMaps[i]->width, this->_ColFeatMaps[i]->height), this->_ColFeatMaps[i]->depth, this->_ColFeatMaps[i]->nChannels);
		IplImage* tmp = cvCreateImage(cvSize(this->_ColFeatMaps[i]->width, this->_ColFeatMaps[i]->height), this->_ColFeatMaps[i]->depth, this->_ColFeatMaps[i]->nChannels);
		IplImage* tmp = cvCreateImage(cvSize(this->_ColScaleImgPyr[i][0][0]->width, this->_ColScaleImgPyr[i][0][0]->height), this->_ColScaleImgPyr[i][0][0]->depth, this->_ColScaleImgPyr[i][0][0]->nChannels);
		for (int j = 0; j < this->_numOfSurScale; j++)
			for (int k = 0; k < this->_numOfScalePyrLevel; k++)
			{
				cvResize(this->_ColScaleImgPyr[i][j][k], tmpimg,CV_INTER_NN);
				//cvAdd(this->_ColFeatMaps[i], tmpimg, this->_ColFeatMaps[i]);
				//IplImage* tmp = cvCloneImage(this->_ColFeatMaps[i]);
				cvCopy(this->_ColFeatMaps[i], tmp);
				cvAddWeighted(tmp, 1.0, tmpimg, (double) 1.0 / this->_numOfSurScale / this->_numOfPyrLevel, 0.0, this->_ColFeatMaps[i]);
				//cvAdd(tmp, tmpimg, this->_ColFeatMaps[i]);
				//cvNormalize(this->_ColFeatMaps[i],this->_ColFeatMaps[i]);
			}
		//IplImage* tmp = cvCloneImage(this->_OriFeatMaps[i]);
		//cvScale(tmp, this->_OriFeatMaps[i], (double)1.0 / this->_numOfPyrLevel / this->_numOfSurScale);
		//cvCopy(this->_ColFeatMaps[i], tmp);
		//cvNormalize(tmp, this->_ColFeatMaps[i], 255, 0, CV_MINMAX);
		cvReleaseImage(&tmpimg);
		cvReleaseImage(&tmp);
	}
}

void VOCUS::_computeIntConsMap()
{
	this->_IntConspImg = cvCreateImage(cvSize(this->_IntFeatMaps[0]->width, this->_IntFeatMaps[0]->height), this->_IntFeatMaps[0]->depth, this->_IntFeatMaps[0]->nChannels);
	cvSet(this->_IntConspImg, cvScalar(0));
	IplImage* tmp = cvCloneImage(this->_IntConspImg);
	double maxAll = 0.0;
	for (int i = 0; i < this->_OnOffsize; i++)
	{
		int localmaxCount;
		double tmpmax;
		this->_IntFeatMaps[i] = this->_Gaussian3x3Smooth(this->_IntFeatMaps[i]);
		this->_findLocalMaximum(this->_IntFeatMaps[i], &localmaxCount, &tmpmax);
		if (tmpmax > maxAll)
			maxAll = tmpmax;
		cout << "localmax int: " << localmaxCount << endl;
		//system("pause");
<<<<<<< .mine
		cvCopy(this->_IntConspImg, tmp);
		cvAddWeighted(tmp, 1.0, this->_IntFeatMaps[i], (double)(1.0 / (double)sqrt((double)localmaxCount)), 0.0, this->_IntConspImg);
		//cvAdd(tmp, this->_IntFeatMaps[i], this->_IntConspImg);
=======
		IplImage* tmp = cvCloneImage(this->_IntConspImg);
		cvAddWeighted(tmp, 1.0, this->_IntFeatMaps[i], (double)(1.0 / (double)sqrt((double)localmaxCount)), 0.0, this->_IntConspImg);
		//cvAdd(tmp, this->_IntFeatMaps[i], this->_IntConspImg);
>>>>>>> .r5
		//cvNormalize(this->_IntConspImg,this->_IntConspImg,255,0,CV_MINMAX,NULL);
		//cvShowImage("ii", this->_IntConspImg);
		//cvWaitKey(0);
	}
<<<<<<< .mine
	cvCopy(this->_IntConspImg, tmp);
	cvNormalize(tmp,this->_IntConspImg,(int)maxAll,0,CV_MINMAX,NULL);
	cvReleaseImage(&tmp);
=======
	IplImage* tmp = cvCloneImage(this->_IntConspImg);
	cvNormalize(tmp,this->_IntConspImg,(int)maxAll,0,CV_MINMAX,NULL);
>>>>>>> .r5
}
void VOCUS::_computeOriConsMap()
{
	this->_OriConspImg = cvCreateImage(cvSize(this->_OriFeatMaps[0]->width, this->_OriFeatMaps[0]->height), this->_OriFeatMaps[0]->depth, this->_OriFeatMaps[0]->nChannels);
	cvSet(this->_OriConspImg, cvScalar(0));
	IplImage* tmp = cvCloneImage(this->_OriConspImg);
	double maxAll = 0.0;
	for (int i = 0; i < this->_numOfOri; i++)
	{
		int localmaxCount;
		double tmpmax;
		this->_OriFeatMaps[i] = this->_Gaussian3x3Smooth(this->_OriFeatMaps[i]);
		this->_findLocalMaximum(this->_OriFeatMaps[i], &localmaxCount, &tmpmax);
		if (tmpmax > maxAll)
			maxAll = tmpmax;
		cout << "localmax ori: " << localmaxCount << endl;
		//system("pause");
<<<<<<< .mine
		cvCopy(this->_OriConspImg, tmp);
		cvAddWeighted(tmp, 1.0, this->_OriFeatMaps[i], (double)(1.0 / (double)sqrt((double)localmaxCount)), 0.0, this->_OriConspImg);
		//cvAdd(tmp, this->_OriFeatMaps[i], this->_OriConspImg);
=======
		IplImage* tmp = cvCloneImage(this->_OriConspImg);
		cvAddWeighted(tmp, 1.0, this->_OriFeatMaps[i], (double)(1.0 / (double)sqrt((double)localmaxCount)), 0.0, this->_OriConspImg);
		//cvAdd(tmp, this->_OriFeatMaps[i], this->_OriConspImg);
>>>>>>> .r5
		//cvNormalize(this->_IntConspImg,this->_IntConspImg,255,0,CV_MINMAX,NULL);
		//cvShowImage("ii", this->_IntConspImg);
		//cvWaitKey(0);
	}
<<<<<<< .mine
	cvCopy(this->_OriConspImg, tmp);
	cvNormalize(tmp, this->_OriConspImg,(int)maxAll,0,CV_MINMAX,NULL);
	cvReleaseImage(&tmp);
=======
	IplImage* tmp = cvCloneImage(this->_OriConspImg);
	cvNormalize(tmp, this->_OriConspImg,(int)maxAll,0,CV_MINMAX,NULL);
>>>>>>> .r5
}
void VOCUS::_computeColConsMap()
{
	this->_ColConspImg = cvCreateImage(cvSize(this->_ColFeatMaps[0]->width, this->_ColFeatMaps[0]->height), this->_ColFeatMaps[0]->depth, this->_ColFeatMaps[0]->nChannels);
	cvSet(this->_ColConspImg, cvScalar(0));
	IplImage* tmp = cvCloneImage(this->_ColConspImg);
	double maxAll = 0.0;
	for (int i = 0; i < this->_numOfColor; i++)
	{
		int localmaxCount;
		double tmpmax;
		this->_ColFeatMaps[i] = this->_Gaussian3x3Smooth(this->_ColFeatMaps[i]);
		this->_findLocalMaximum(this->_ColFeatMaps[i], &localmaxCount, &tmpmax);
		if (tmpmax > maxAll)
			maxAll = tmpmax;
		cout << "localmax col: " << localmaxCount << endl;
		//system("pause");
<<<<<<< .mine
		//IplImage* tmp = cvCloneImage(this->_ColConspImg);
		cvCopy(this->_ColConspImg, tmp);
		cvAddWeighted(tmp, 1.0, this->_ColFeatMaps[i], (double)(1.0 / (double)sqrt((double)localmaxCount)), 0.0, this->_ColConspImg);
		//cvAdd(tmp, this->_ColFeatMaps[i], this->_ColConspImg);
=======
		IplImage* tmp = cvCloneImage(this->_ColConspImg);
		cvAddWeighted(tmp, 1.0, this->_ColFeatMaps[i], (double)(1.0 / (double)sqrt((double)localmaxCount)), 0.0, this->_ColConspImg);
		//cvAdd(tmp, this->_ColFeatMaps[i], this->_ColConspImg);
>>>>>>> .r5
		//cvNormalize(this->_IntConspImg,this->_IntConspImg,255,0,CV_MINMAX,NULL);
		//cvShowImage("ii", this->_IntConspImg);
		//cvWaitKey(0);
	}
<<<<<<< .mine
	cvCopy(this->_ColConspImg, tmp);
	cvNormalize(tmp, this->_ColConspImg,(int)maxAll,0,CV_MINMAX,NULL);
	cvReleaseImage(&tmp);
=======
	IplImage* tmp = cvCloneImage(this->_ColConspImg);
	cvNormalize(tmp, this->_ColConspImg,(int)maxAll,0,CV_MINMAX,NULL);
>>>>>>> .r5
}

void VOCUS::_computeSaliencyMap()
{
	this->_SaliencyMap = cvCreateImage(cvSize(this->_ColConspImg->width, this->_ColConspImg->height), this->_ColConspImg->depth, this->_ColConspImg->nChannels);
	cvSet(this->_SaliencyMap, cvScalar(0));
	double tmpmax, maxall = 0;
	int localmaxCount;
	this->_findLocalMaximum(this->_IntConspImg, &localmaxCount, &tmpmax);
	maxall = tmpmax > maxall ? tmpmax : maxall;
	cvAddWeighted(this->_SaliencyMap, 1.0, this->_IntConspImg, (double)(1.0 / (double)sqrt((double)localmaxCount)), 0.0, this->_SaliencyMap);
	this->_findLocalMaximum(this->_OriConspImg, &localmaxCount, &tmpmax);
	maxall = tmpmax > maxall ? tmpmax : maxall;
	cvAddWeighted(this->_SaliencyMap, 1.0, this->_OriConspImg, (double)(1.0 / (double)sqrt((double)localmaxCount)), 0.0, this->_SaliencyMap);
	this->_findLocalMaximum(this->_ColConspImg, &localmaxCount, &tmpmax);
	maxall = tmpmax > maxall ? tmpmax : maxall;
	cvAddWeighted(this->_SaliencyMap, 1.0, this->_ColConspImg, (double)(1.0 / (double)sqrt((double)localmaxCount)), 0.0, this->_SaliencyMap);

	IplImage* tmp = cvCloneImage(this->_SaliencyMap);
	cvNormalize(tmp, this->_SaliencyMap, (int)maxall, 0, CV_MINMAX, NULL);
	cvReleaseImage(&tmp);
}

void VOCUS::_computeMSR()
{
	int msp_x, msp_y, msp_v = 0;
	for (int i = 0; i < this->_SaliencyMap->width; i++)
		for (int j = 0; j < this->_SaliencyMap->height; j++)
		{
			if (((uchar*)(this->_SaliencyMap->imageData + this->_SaliencyMap->widthStep * j))[i] > msp_v)
			{
				msp_v = ((uchar*)(this->_SaliencyMap->imageData + this->_SaliencyMap->widthStep * j))[i];
				msp_x = j; msp_y = i;
			}
		}
	cvFloodFill(this->_SaliencyMap, Point(msp_y, msp_x), cvScalar(255), cvScalarAll((int)(this->_floodfillRatio * msp_v)), cvScalarAll(0), NULL, 4, NULL);
}

void VOCUS::_findLocalMaximum(IplImage* img, int* numLocalMax, double* Mmax)
{
	// Get global maximum
	double globalmax = 0.0;
	for(int i = 0; i < img->width; i++)
		for(int j = 0; j < img->height; j++)
		{
			double pixel = (int)((uchar*)(img->imageData + img->widthStep * j))[i];//cvmGet(img, i, j);
			if (pixel > globalmax)
				globalmax = pixel;
		}

	//cout << "global max " << globalmax << " thres " << this->_localMaxThres_ratio2Global * globalmax << endl;
	//IplImage* tempimg = cvCloneImage(img);
	//cvSet(tempimg, cvScalar(0));

	// Count Local Maximum
	int countLocal = 0;
	bool flag = false;
	for(int i = 1; i < img->width - 1; i++)
		for(int j = 1; j < img->height - 1; j++)
		{
			flag = true;
			double val = (int)((uchar*)(img->imageData + img->widthStep * j))[i];//cvmGet(img, i, j);
			if (val <= this->_localMaxThres_ratio2Global * globalmax)
			{
				continue;
			}
			//compare with the neighbor
			for(int m = -1; flag && m <= 1; m++)
				for(int n = -1; flag && n <= 1; n++)
				{
					double temp = (int)((uchar*)(img->imageData + img->widthStep * (j+n)))[(i+m)];//cvmGet(src, i + m, j + n);
					if(m != 0 && n != 0 && val <= temp)
					{
						flag = false;
					}
				}
			if(flag)
			{
				//((uchar*)(tempimg->imageData + tempimg->widthStep * j))[i] = 255;
				countLocal++;
				j++;  //the next pixel is absolutely is not maxima 
			}
		}
	//cvShowImage("max", tempimg);
	//cvWaitKey(0);
	*Mmax = globalmax;
	*numLocalMax = countLocal;
}
void VOCUS::_OnCenterFilter(IplImage* src, IplImage* dst, int scale)
{
	for (int x = 0; x < src->height; x++)
		for (int y = 0; y < src->width; y++)
		{
			int center = (int)((uchar*)(src->imageData + src->widthStep * x))[y];
			double surround = 0;
			int count = 0;
			for (int i = -scale + x; i <= scale + x; i++)
				for (int j = -scale + y; j <= scale + y; j++)
					if (i >=0 && i < src->height && j >=0 && j < src->width)
					{
						if ( i == x && j == y)
							continue;
						int pixelvalue = (int)((uchar*)(src->imageData + src->widthStep * i))[j];
						surround += pixelvalue;
						count++;
					}
			double meanvalue = surround / count;
			//((uchar*)(img->imageData + img->widthStep * x))[y] = center - meanvalue;
			if (center - meanvalue <= 0)
				((uchar*)(dst->imageData + dst->widthStep * x))[y] = 0;
			else
			{
				((uchar*)(dst->imageData + dst->widthStep * x))[y] = (uchar)((int)(center - meanvalue + 0.5));
				//cout << "center " << center << " meanvalue " << meanvalue << " value " << (int)((uchar*)(img->imageData + img->widthStep * x))[y] << endl;
			}
			//cout << (int)((uchar*)(img->imageData + img->widthStep * x))[y] << endl;
		}
}
void VOCUS::_OffCenterFilter(IplImage* src, IplImage* dst, int scale)
{
	for (int x = 0; x < src->height; x++)
		for (int y = 0; y < src->width; y++)
		{
			int center = (int)((uchar*)(src->imageData + src->widthStep * x))[y];
			double surround = 0;
			int count = 0;
			for (int i = -scale + x; i <= scale + x; i++)
				for (int j = -scale + y; j <= scale + y; j++)
					if (i >= 0 && i < src->height && j >=0 && j < src->width)
					{
						if (i == x && y == j)
							continue;
						int pixelvalue = (int)((uchar*)(src->imageData + src->widthStep * i))[j];
						surround += pixelvalue;
						count++;
					}
			double meanvalue = surround / count;
			if (meanvalue - center <= 0)
				((uchar*)(dst->imageData + dst->widthStep * x))[y] = 0;
			else
			{
				((uchar*)(dst->imageData + dst->widthStep * x))[y] = (uchar)((int)(meanvalue - center + 0.5));
				//cout << "center " << center << " meanvalue " << meanvalue << " value " << (int)((uchar*)(img->imageData + img->widthStep * x))[y] << endl;
			}
		}
}

bool VOCUS::loadImage(IplImage* img)
{
	if (!img)
		return false;
	this->_originImg = cvCloneImage(img);
	return true;
}
bool VOCUS::loadImageFromPath(string path)
{
	this->_originImg = cvLoadImage(path.c_str(), 1);
	if (!this->_originImg)
		return false;
	return true;
}
bool VOCUS::loadConfig(string filePath)
{
	FileStorage fs;
	fs.open(filePath, cv::FileStorage::READ);
	this->loadConfig(fs);
	return true;
}
bool VOCUS::loadConfig(FileStorage fsAll)
{
	FileNode fs = fsAll["VocusParameter"];
	if (fs.empty())
		return false;

<<<<<<< .mine
	this->_imgPath = fs["ImagePath"];

	FileNode general = fs["GeneralParameter"];
	general["NumberOfPyramidLevel"] >> this->_numOfPyrLevel;
	general["NumberOfOrientation"] >> this->_numOfOri;
	general["NumberOfColor"] >> this->_numOfColor;
	general["NumberOfSurroundScale"] >> this->_numOfSurScale;

	FileNode surscale = fs["SurroundScale"];
	for (int i = 0; i < this->_numOfSurScale; i++)
		this->_surr_scale[i] = surscale[i];

	FileNode ori = fs["OrientationAngle"];
	for (int i = 0; i < this->_numOfOri; i++)
		this->_ori_angle[i] = ori[i];

	FileNode gabor = fs["Gabor"];
	gabor["Sigma"] >> this->_gabor_sigma;
	gabor["F"] >> this->_gabor_f;
	gabor["Scale"] >> this->_gabor_scale;

	fs["LocalMaxThresholdRatio2Global"] >> this->_localMaxThres_ratio2Global;
	fs["FloodFill"]["Ratio"] >> this->_floodfillRatio;

	return true;
}
IplImage*  VOCUS::getResult()
=======
	FileNode general = fs["GeneralParameter"];
	general["NumberOfPyramidLevel"] >> this->_numOfPyrLevel;
	general["NumberOfOrientation"] >> this->_numOfOri;
	general["NumberOfColor"] >> this->_numOfColor;
	general["NumberOfSurroundScale"] >> this->_numOfSurScale;

	FileNode surscale = fs["SurroundScale"];
	for (int i = 0; i < this->_numOfSurScale; i++)
		this->_surr_scale[i] = surscale[i];

	FileNode ori = fs["OrientationAngle"];
	for (int i = 0; i < this->_numOfOri; i++)
		this->_ori_angle[i] = ori[i];

	FileNode gabor = fs["Gabor"];
	gabor["Sigma"] >> this->_gabor_sigma;
	gabor["F"] >> this->_gabor_f;
	gabor["Scale"] >> this->_gabor_scale;

	fs["LocalMaxThresholdRatio2Global"] >> this->_localMaxThres_ratio2Global;
	fs["FloodFill"]["Ratio"] >> this->_floodfillRatio;

	return true;
}

void VOCUS::_showPyr(vector<IplImage*> imgVec)
>>>>>>> .r5
{
	IplImage* result = cvCloneImage(this->_SaliencyMap);
	return result;
}
IplImage*  VOCUS::getOrigin()
{
	IplImage* result = cvCloneImage(this->_originImg);
	return result;
}
void VOCUS::_showPyr(string winname, vector<IplImage*> imgVec)
{
	IplImage* showimg = cvCreateImage(cvSize(imgVec[0]->width * 2, imgVec[0]->height),imgVec[0]->depth,imgVec[0]->nChannels);
	Point leftUpCorner(0,0);
	for (vector<IplImage* >::iterator itb = imgVec.begin(); itb != imgVec.end(); itb++)
	{
		assert(*itb != NULL);
		CvRect rect = cvRect(leftUpCorner.x, leftUpCorner.y, (*itb)->width, (*itb)->height);
		leftUpCorner.x += (*itb)->width;
		cvSetImageROI(showimg, rect);
		cvCopy((*itb), showimg);
		cvResetImageROI(showimg);
	}
	if (this->_showProcess)
	{
		cvShowImage(winname.c_str(), showimg);
		cvWaitKey(0);
	}
	cvReleaseImage(&showimg);
}
void VOCUS::_showSingleImage(string winname, IplImage* img)
{
	if (this->_showProcess)
	{
		cvShowImage(winname.c_str(), img);
		cvWaitKey(0);
	}
}

void VOCUS::_init()
{
	//	Initialize Pyramids
	this->_IntImgPyr.resize(this->_numOfPyrLevel);	//	Intensity Pyramid
	this->_OriLapPyr.resize(this->_numOfPyrLevel);	//	Orientation Pyramid
	this->_ColImgPyr.resize(this->_numOfColor,vector<IplImage*>(this->_numOfPyrLevel));	//	Color Pyramid

	//	Initialize Scale Maps
	this->_IntScaleImgPyr.resize(this->_OnOffsize,vector<vector<IplImage*>>(this->_numOfSurScale, vector<IplImage*>(this->_numOfScalePyrLevel)));	//	Intensity Scale Map
	this->_OriScaleImgPyr.resize(this->_numOfOri,vector<IplImage*>(this->_numOfScalePyrLevel));	//	Orientation Scale Map
	this->_ColScaleImgPyr.resize(this->_numOfColor,vector<vector<IplImage*>>(this->_numOfSurScale, vector<IplImage*>(this->_numOfScalePyrLevel)));	//	Color Scale Map

	//	Initialize Feature Maps
	this->_IntFeatMaps.resize(this->_OnOffsize);
	this->_OriFeatMaps.resize(this->_numOfOri);
	this->_ColFeatMaps.resize(this->_numOfColor);
}
void VOCUS::_release()
{
	cvReleaseImage(&this->_originImg);
	cvReleaseImage(&this->_IntConspImg);
	cvReleaseImage(&this->_OriConspImg);
	cvReleaseImage(&this->_ColConspImg);
	cvReleaseImage(&this->_SaliencyMap);

	for (int i = 0;i < this->_numOfPyrLevel; i++)
	{
		//Release Pyramids
		cvReleaseImage(&this->_IntImgPyr[i]);
		cvReleaseImage(&this->_OriLapPyr[i]);
		for (int j = 0; j < this->_numOfColor; j++)
			cvReleaseImage(&this->_ColImgPyr[j][i]);
	}
	for (int i = 0;i < this->_numOfScalePyrLevel; i++)
	{
		//Release Scale Maps
		for (int j = 0; j < this->_OnOffsize; j++)
			for (int k = 0; k < this->_numOfSurScale; k++)
				cvReleaseImage(&this->_IntScaleImgPyr[j][k][i]);
		for (int j = 0; j < this->_numOfOri; j++)
			cvReleaseImage(&this->_OriScaleImgPyr[j][i]);
		for (int j = 0; j < this->_numOfColor; j++)
			for (int k = 0; k < this->_numOfSurScale; k++)
				cvReleaseImage(&this->_ColScaleImgPyr[j][k][i]);
		
	}
	//Release Feature Maps
	for (int i = 0; i < this->_OnOffsize; i++)
		cvReleaseImage(&this->_IntFeatMaps[i]);
	for (int i = 0; i < this->_numOfOri; i++)
		cvReleaseImage(&this->_OriFeatMaps[i]);
	for (int i = 0; i < this->_numOfColor; i++)
		cvReleaseImage(&this->_ColFeatMaps[i]);
}
IplImage* VOCUS::_Gaussian3x3Smooth(IplImage* img)
{
	IplImage* resultImg = cvCreateImage(cvSize(img->width,img->height), img->depth, img->nChannels);
	float k[9] = { 0.0625, 0.125, 0.0625,
		0.125, 0.25, 0.125,
		0.0625, 0.125, 0.0625};  
	CvMat km = cvMat( 3, 3, CV_32FC1, k );
	cvFilter2D(img, resultImg, &km, cvPoint(-1,-1));
	return resultImg;
}
float VOCUS::_dist(Point2i a, Point2i b)
{
	//cout << a.x << " " << a.y << " " << b.x << " " << b.y << " " << (int)((a.x - b.x)*(a.x - b.x) + (a.y - b.y)*(a.y - b.y)) << endl;
	return (float)sqrt(((float)a.x - b.x)*(a.x - b.x) + (a.y - b.y)*(a.y - b.y));
}
void VOCUS::_ab2rgyb(int a, int b, int* red, int* green, int* yellow, int* blue)
{
	int newa = (a - 128) * 2, newb = (b - 128) * 2;
	if (newa > 0)
	{
		*green = 0;
		*red = newa;
	}
	else
	{
		*green = (int)abs(newa);
		*red = 0;
	}
	if (newb > 0)
	{
		*blue = 0;
		*yellow = newb;//(int)abs(newa) < 50 ? newb : 0;
	}
	else
	{
		*blue = (int)abs(newb);
		*yellow = 0;
	}
}


